import { ref, watch, type Ref } from "vue"

type RequestFunc<T> = () => Promise<T | undefined>
interface RequestError { code: number, message: string }

export default function useRequest<T>(requestFunc: RequestFunc<T>, watchSource: Ref<any>[] = []) {
    const result = ref<T>() as Ref<T>
    const loading = ref(false)
    const error = ref<RequestError | null>(null)


    const doRequest = async () => {
        loading.value = true
        error.value = null
        try {
            result.value = await requestFunc() as T
        } catch (e) {
            error.value = e as RequestError
        } finally {
            loading.value = false
        }
    }


    watch([...watchSource], doRequest)

    return { doRequest, result, loading, error }
}